package com.xbongbong.saas.analytical.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.team.TeamUserHelp;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataRepeatVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.pro.common.pojo.dto.RepeatCommonConditionDTO;
import com.xbongbong.pro.constant.AttrLenthConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.saas.analytical.SaasValidateAnalyticalService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.help.AnalyticalHelp;
import com.xbongbong.saas.help.SaasBomBillHelp;
import com.xbongbong.saas.help.SaasProductHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.util.ValidateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @date 2021/07/15 17:15
 */
@Service("bomBillAnalyticalServiceImpl")
public class BomBillValidateAnalyticalServiceImpl implements SaasValidateAnalyticalService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(BomBillValidateAnalyticalServiceImpl.class);

    @Resource
    private CommonHelp commonHelp;
    @Resource
    private ProductModel productModel;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private SaasProductHelp saasProductHelp;
    @Resource
    private SaasBomBillHelp saasBomBillHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private AnalyticalHelp analyticalHelp;
    @Resource
    private TeamUserHelp teamUserHelp;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.BOM_BILL.getCode());
    }

    @Override
    public void analyticalData(ValidateDataDTO validateDataDTO) throws XbbException {
        beforeSave(validateDataDTO);
        teamUserHelp.beforeVerifyUserTeam(validateDataDTO);
    }
    
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        try {
            JSONObject data = validateDataDTO.getData();
            String corpid = validateDataDTO.getCorpid();
            FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
            Map<String, FieldAttrEntity> explainMap = validateDataDTO.getExplainMap();
            FieldAttrEntity sheetNo = explainMap.getOrDefault(BomBillEnum.SHEET_NO.getAttr(), fieldAttrEntity);
            // 校验编号长度不超过100且编号存在
            if (Objects.nonNull(sheetNo) && Objects.equals(sheetNo.getStrictController(), BasicConstant.ZERO)) {
                ValidateUtil.checkSerialNumber(validateDataDTO.getSerialNo(), Objects.toString(sheetNo.getAttrName(), ""));
            }

            FieldAttrEntity memoField = explainMap.getOrDefault(BomBillEnum.MEMO.getAttr(), fieldAttrEntity);
            // 校验备注长度
            ValidateUtil.checkFieldEntityLength(data, BomBillEnum.MEMO.getAttr(), Objects.toString(memoField.getAttrName(), ""), AttrLenthConstant.MEMO_MAX_LENGTH);

            // bom版本
            SaveFormatHelp.formatTextCheck4Save(data, BomBillEnum.VERSION.getAttr(), BomBillEnum.VERSION_LINK_TEXT.getAttr());
            SaveFormatHelp.dataCheckForSaas(data, corpid);
            boolean isNew = analyticalHelp.isNew(validateDataDTO.getDataId(), validateDataDTO.getTaskId(), corpid);;
            Long bomId = validateDataDTO.getDataId() == null ? 0L : validateDataDTO.getDataId();
            JSONArray productArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,BomBillEnum.PRODUCT.getAttr(),new JSONArray());
            JSONArray materielProductarray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,BomBillEnum.MATERIEL.getAttr(),new JSONArray());
            String version = FastJsonHelper.getStringFromFormData(data, BomBillEnum.VERSION.getAttr());
            RepeatCommonConditionDTO repeatCommonConditionDTO = new RepeatCommonConditionDTO();
            BeanUtil.copyProperties(validateDataDTO, repeatCommonConditionDTO);
            Boolean productCanSee = true;
            Boolean materielCanSee = true;
            if (!isNew) {
                productCanSee = commonHelp.attrCanSee(validateDataDTO.getExplainMap().get(BomBillEnum.PRODUCT.getAttr()),validateDataDTO.getDataId(),validateDataDTO.getCreatorId(),validateDataDTO.getLoginUser(),validateDataDTO.getCorpid(),XbbRefTypeEnum.BOM_BILL.getCode());
                materielCanSee = commonHelp.attrCanSee(validateDataDTO.getExplainMap().get(BomBillEnum.MATERIEL.getAttr()),validateDataDTO.getDataId(),validateDataDTO.getCreatorId(),validateDataDTO.getLoginUser(),validateDataDTO.getCorpid(),XbbRefTypeEnum.BOM_BILL.getCode());
            }
            validateDataProduct(productArray,materielProductarray,data,version,corpid,bomId,isNew,productCanSee,materielCanSee);
            validateDataDTO.setData(data);
            Map<String,Boolean> attrCanSeeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            attrCanSeeMap.put(BomBillEnum.PRODUCT.getAttr(),productCanSee);
            attrCanSeeMap.put(BomBillEnum.MATERIEL.getAttr(),materielCanSee);
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
            saasNeedRedundantAttrPojo.setAttrCanSeeMap(attrCanSeeMap);
            validateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("bomBillAnalyticalServiceImpl.beforeSave error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 校验生产单产品
     * @param productArray 成品产品
     * @param materielProductarray 物料产品
     * @param data 数据
     * @param version 版本
     * @param corpid 公司id
     * @param bomId bom单Id
     * @param isNew 是否新建
     * @param productCanSee 成品可见
     * @param materielCanSee 物料可见
     */
    private void validateDataProduct(JSONArray productArray, JSONArray materielProductarray, JSONObject data, String version, String corpid, Long bomId, boolean isNew, Boolean productCanSee, Boolean materielCanSee) throws XbbException {
        Set<Long> pageProductIds = new HashSet<>();
        if (isNew || productCanSee){
            //新建或编辑可见产品字段
            if (productArray.size() > 1){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, ErrorMessageConstant.ONLY_ONE_PRODUCT);
            }
            RepeatCommonConditionDTO repeatCommonConditionDTO = new RepeatCommonConditionDTO();
            repeatCommonConditionDTO.setBusinessType(XbbRefTypeEnum.BOM_BILL.getCode());
            repeatCommonConditionDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            for (Object obj : productArray){
                JSONObject json = JSONObject.parseObject(obj.toString());
                Long productId = json.getLong(SelectProductEnum.PRODUCT.getAttr());
                pageProductIds.add(productId);
                FormDataRepeatVO formDataRepeatVO = saasBomBillHelp.checkRepeatForBomVersion(repeatCommonConditionDTO, version, null, productId, true);
                saveBomVersionCheckRepeat(formDataRepeatVO, bomId);
                ProductEntityExt productEntityExt = productModel.getByKey(productId,corpid);
                formDataHelp.setChildSpecification(Collections.singletonList(productEntityExt),corpid);
                JSONObject productData = productEntityExt.getData();
                String productName = productData.getString(ProductEnum.NAME.getAttr());
                productName = productName == null ? "" : productName;
                String productNo = productEntityExt.getSerialNo();
                productNo = productNo == null ? "" : productNo;
                Long formId = productEntityExt.getFormId();
                Map<String, String> dictionaryMap4Saas = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.PRODUCT_UNIT, corpid, formId);
                String unit = dictionaryMap4Saas.get(productData.getString(ProductEnum.UNIT.getAttr()));
                String productSpecification = productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                productSpecification = productSpecification == null ? "" : productSpecification;
                data.put(BomBillEnum.PRODUCT_NAME.getAttr(), productId.toString());
                data.put(BomBillEnum.PRODUCT_NAME_HIDE.getAttr(), productName);
                data.put(BomBillEnum.PRODUCT_NO.getAttr(), productNo);
                data.put(BomBillEnum.PRODUCT_SPECIFICATION.getAttr(), productSpecification);
                data.put(BomBillEnum.PRODUCT_UNIT.getAttr(), unit);
            }
        }
        if (isNew || materielCanSee) {
            //新建或编辑可见产品字段
            for (Object obj : materielProductarray){
                JSONObject json = JSONObject.parseObject(obj.toString());
                Long productId = json.getLong(SelectProductEnum.PRODUCT.getAttr());
                pageProductIds.add(productId);
            }
        }
        saasProductHelp.productExit(corpid,new ArrayList<>(pageProductIds));
    }

    /**
     * 保存时返回查重错误
     *
     * @param formDataRepeatVO 查重返回vo
     * @param bomId bom清单id
     * @author feng.zheng
     * @date 2019/2/19 21:54
     */
    private void saveBomVersionCheckRepeat(FormDataRepeatVO formDataRepeatVO, Long bomId) throws XbbException{
        // 用于保存时返回
        if (Objects.isNull(formDataRepeatVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.REPEAT_DATA_FAILED);
        }
        List<PaasFormDataEntityExt> formDataList = formDataRepeatVO.getFormDataList();
        if (Objects.isNull(formDataList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        if (!formDataList.isEmpty() && formDataList.size() > 1) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DUPLICATE_VALUE, I18nMessageUtil.getMessage(StringConstant.BOM_VERSION));
        }
        if (formDataList.size() == 1 && !Objects.equals(formDataList.get(0).getDataId(), bomId)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DUPLICATE_VALUE, I18nMessageUtil.getMessage(StringConstant.BOM_VERSION));
        }
    }
}
